import { getConfig } from "@/config";
import { Client } from "@stomp/stompjs";
import { defineStore } from "pinia";
import { getToken } from "@/utils/auth";
import type { StompType } from "@/store/modules/types";
import { store } from "@/store";
import { isJSON } from "@pureadmin/utils";
import { message } from "@/utils/message";

const { VITE_WS_BASE_URL } = import.meta.env;

const stompUrl = `${getConfig("WsBaseUrl") ? getConfig("WsBaseUrl") : VITE_WS_BASE_URL}`;

const useStompJsStore = defineStore({
  id: "StompJs",
  state: (): StompType => ({
    client: null,
    // 重连后重新订阅
    listenerSubs: []
  }),
  getters: {
    stompClient: state => state.client
  },
  actions: {
    // 激活stomp客户端
    Activate() {
      const header = {};
      header[getToken().tokenKey] = getToken().accessToken;
      this.client = new Client({
        brokerURL: stompUrl,
        connectHeaders: header,
        reconnectDelay: 5000,
        connectionTimeout: 5000,
        heartbeatIncoming: 1000,
        heartbeatOutgoing: 1000
      });

      this.client.onConnect = frame => {
        if (frame.command === "CONNECTED") {
          // 重连后取listenerSubs中存在的订阅重新连接，避免在每个订阅中判断是否为CONNECTED状态
          for (let sub of this.listenerSubs) {
            this.Subscribe(sub.topic, sub.callback, false);
          }
        }
        // Do something, all subscribes must be done is this callback
        // This is needed because this will be executed after a (re)connect
      };
      this.client.onStompError = frame => {
        message(`消息服务异常:${frame.headers.message}`, {
          type: "error"
        });
      };
      this.client.activate();
    },
    /**
     *
     * @param topic 订阅路径
     * @param callback 订阅回调
     * @param isRemoveDup 是否需要移除重复订阅
     */
    // 目前还未尝试两个相同订阅，是否会产生前一个订阅数据无法获得的问题
    Subscribe<T>(
      topic: string,
      callback: (msg: T) => void,
      isRemoveDup = true
    ) {
      const header = {};
      header[getToken().tokenKey] = getToken().accessToken;
      if (!this.client) {
        this.Activate();
      }
      if (!this.client.connected) {
        this.listenerSubs.push({
          topic,
          callback
        });
        return;
      }
      const cb = res => {
        if (isJSON(res.body)) {
          const data = JSON.parse(res.body);
          callback(data);
        } else {
          callback(res.body);
        }
      };
      console.log(`subscribe: ${topic}`);
      this.client.subscribe(topic, cb, header);
      // 此处需要管理重复的订阅
      if (isRemoveDup) {
        this.listenerSubs.push({
          topic,
          callback
        });
      }
    },
    UnSubscribe(topic: string) {
      if (this.client && this.client.connected) {
        console.log(`unsubscribe: ${topic}`);
        this.client.unsubscribe(topic);
        this.listenerSubs.filter(item => {
          return item.topic != topic;
        });
      }
    },
    Send(destination: string, param: Object) {
      if (!this.client) {
        this.Activate();
      }
      const header = {};
      header[getToken().tokenKey] = getToken().accessToken;
      this.client.publish({
        destination: destination,
        headers: header,
        body: JSON.stringify(param)
      });
    },
    // 断开stomp客户端
    async DeActivate() {
      await this.client.deactivate().then(() => {
        this.client = null;
      });
    }
  }
});

export function useStompJsStoreHook() {
  return useStompJsStore(store);
}
